package com.godpaper.the2tigers.busniess.AI
{
	import com.godpaper.the2tigers.busniess.managers.PiecesManager;
	import com.godpaper.the2tigers.model.BoardModel;
	import com.godpaper.the2tigers.model.PiecesModel;
	import com.godpaper.the2tigers.views.components.GasketButton;
	import com.godpaper.the2tigers.views.components.PieceButton;
	import com.godpaper.the2tigers.vo.ConductVO;
	
	import de.polygonal.ds.Array2;
	
	import mx.collections.ArrayCollection;
	
	 /**
	 * @author Knight-errant
	 * This essay is a detailed explanation of one of the most important
	 * data structures ever created for Game Artificial Intelligence. 
	 * The minimax tree is at the heart of almost every board game program in existence.
	 */	
	public class GameAIBase implements IAIBehavior
	{
		protected var bestMove:ConductVO;
		protected var moves:ArrayCollection;//conductVO's collection;
		protected var tempMove:ConductVO;
		protected var positionEvaluation:int;
		
		public function GameAIBase()
		{
			//TODO: implement function
		}
		
		//return all possbility movements;
		public function generateMoves(reds:ArrayCollection, gamePosition:Array2):ArrayCollection
		{
			trace("#####################Game AI generateMoves begin##########################");
			var tempAC:ArrayCollection = new ArrayCollection();
			trace("current GamePosition:",BoardModel.getInstance().gamePosition.dump());
			for(var i:int=0;i<reds.length;i++)
			{
				var redsPB:PieceButton = reds.getItemAt(i) as PieceButton;
				var redsGB:GasketButton = BoardModel.getInstance().gasketsPosition.gett(redsPB.pieceVO.position[0],redsPB.pieceVO.position[1]) as GasketButton;
				trace("current redsPB:",redsPB);
				trace("current redsGB:",redsGB);
				
				var redsPBleft:ArrayCollection = BoardModel.getInstance().gamePosition.gett( redsPB.pieceVO.position[0]-1,redsPB.pieceVO.position[1] ) as ArrayCollection;
				var redsPBtop:ArrayCollection = BoardModel.getInstance().gamePosition.gett( redsPB.pieceVO.position[0],redsPB.pieceVO.position[1]-1 ) as ArrayCollection;
				var redsPBright:ArrayCollection = BoardModel.getInstance().gamePosition.gett( redsPB.pieceVO.position[0]+1,redsPB.pieceVO.position[1] ) as ArrayCollection;
				var redsPBbottom:ArrayCollection = BoardModel.getInstance().gamePosition.gett( redsPB.pieceVO.position[0],redsPB.pieceVO.position[1]+1 ) as ArrayCollection;
				var redsPBlowerLeft:ArrayCollection = BoardModel.getInstance().gamePosition.gett( redsPB.pieceVO.position[0]-1,redsPB.pieceVO.position[1]+1 ) as ArrayCollection;
				var redsPBlowerRight:ArrayCollection = BoardModel.getInstance().gamePosition.gett( redsPB.pieceVO.position[0]+1,redsPB.pieceVO.position[1]+1 ) as ArrayCollection;
				var redsPBupperRight:ArrayCollection = BoardModel.getInstance().gamePosition.gett( redsPB.pieceVO.position[0]+1,redsPB.pieceVO.position[1]-1 ) as ArrayCollection;
				var redsPBupperLeft:ArrayCollection = BoardModel.getInstance().gamePosition.gett( redsPB.pieceVO.position[0]-1,redsPB.pieceVO.position[1]-1 ) as ArrayCollection;
				
				var redsPBleftLeft:ArrayCollection = BoardModel.getInstance().gamePosition.gett( redsPB.pieceVO.position[0]-2,redsPB.pieceVO.position[1] ) as ArrayCollection;
				var redsPBtopTop:ArrayCollection = BoardModel.getInstance().gamePosition.gett( redsPB.pieceVO.position[0],redsPB.pieceVO.position[1]-2 ) as ArrayCollection;
				var redsPBrightRight:ArrayCollection = BoardModel.getInstance().gamePosition.gett( redsPB.pieceVO.position[0]+2,redsPB.pieceVO.position[1] ) as ArrayCollection;
				var redsPBbottomBottom:ArrayCollection = BoardModel.getInstance().gamePosition.gett( redsPB.pieceVO.position[0],redsPB.pieceVO.position[1]+2 ) as ArrayCollection;
				var redsPBlowerLeftLowerLeft:ArrayCollection = BoardModel.getInstance().gamePosition.gett( redsPB.pieceVO.position[0]-2,redsPB.pieceVO.position[1]+2 ) as ArrayCollection;
				var redsPBlowerRightLowerRight:ArrayCollection = BoardModel.getInstance().gamePosition.gett( redsPB.pieceVO.position[0]+2,redsPB.pieceVO.position[1]+2 ) as ArrayCollection;
				var redsPBupperRightUpperRight:ArrayCollection = BoardModel.getInstance().gamePosition.gett( redsPB.pieceVO.position[0]+2,redsPB.pieceVO.position[1]-2 ) as ArrayCollection;
				var redsPBupperLeftUpperLeft:ArrayCollection = BoardModel.getInstance().gamePosition.gett( redsPB.pieceVO.position[0]-2,redsPB.pieceVO.position[1]-2 ) as ArrayCollection;
				trace("--------------------------------------");
				trace("redsPBleft:",redsPBleft);
				trace("redsPBtop:",redsPBtop);
				trace("redsPBright:",redsPBright);
				trace("redsPBbottom:",redsPBbottom);
				trace("redsPBlowerLeft:",redsPBlowerLeft);
				trace("redsPBlowerRight:",redsPBlowerRight);
				trace("redsPBupperRight:",redsPBupperRight);
				trace("redsPBupperLeft:",redsPBupperLeft);
				trace("redsPBleftLeft:",redsPBleftLeft);
				trace("redsPBtopTop:",redsPBtopTop);
				trace("redsPBrightRight:",redsPBrightRight);
				trace("redsPBbottomBottom:",redsPBbottomBottom);
				trace("redsPBlowerLeftLowerLeft:",redsPBlowerLeftLowerLeft);
				trace("redsPBlowerRightLowerRight:",redsPBlowerRightLowerRight);
				trace("redsPBupperRightUpperRight:",redsPBupperRightUpperRight);
				trace("redsPBupperLeftUpperLeft:",redsPBupperLeftUpperLeft);
				trace("--------------------------------------");
				//left
				if(redsPBleft==null && redsGB.left!=null)
				{
					var conductVOleft:ConductVO = new ConductVO();
					conductVOleft.target = redsPB;
					conductVOleft.newDest = redsGB.left.centerPointXY;
					conductVOleft.newPosition = redsGB.left.position;
					tempAC.addItem(conductVOleft);
				}else
				{
					if(redsPBleftLeft==null && redsGB.left!=null && redsGB.left.left!=null)
					{
						var conductVOleftLeft:ConductVO = new ConductVO();
						conductVOleftLeft.target = redsPB;
						conductVOleftLeft.newDest = redsGB.left.left.centerPointXY;
						conductVOleftLeft.newPosition = redsGB.left.left.position;
						tempAC.addItem(conductVOleftLeft);
					}
				}
				//top
				if(redsPBtop==null && redsGB.top!=null)
				{
					var conductVOtop:ConductVO = new ConductVO();
					conductVOtop.target = redsPB;
					conductVOtop.newDest = redsGB.top.centerPointXY;
					conductVOtop.newPosition = redsGB.top.position;
					tempAC.addItem(conductVOtop);
				}else
				{
					if(redsPBtopTop==null && redsGB.top!=null && redsGB.top.top!=null)
					{
						var conductVOtopTop:ConductVO = new ConductVO();
						conductVOtopTop.target = redsPB;
						conductVOtopTop.newDest = redsGB.top.top.centerPointXY;
						conductVOtopTop.newPosition = redsGB.top.top.position;
						tempAC.addItem(conductVOtopTop);
					}
				}
				//right
				if(redsPBright==null && redsGB.right!=null)
				{
					var conductVOright:ConductVO = new ConductVO();
					conductVOright.target = redsPB;
					conductVOright.newDest = redsGB.right.centerPointXY;
					conductVOright.newPosition = redsGB.right.position;
					tempAC.addItem(conductVOright);
				}else
				{
					if(redsPBrightRight==null && redsGB.right!=null && redsGB.right.right!=null)
					{
						var conductVOrightRight:ConductVO = new ConductVO();
						conductVOrightRight.target = redsPB;
						conductVOrightRight.newDest = redsGB.right.centerPointXY;
						conductVOrightRight.newPosition = redsGB.right.right.position;
						tempAC.addItem(conductVOrightRight);
					}
				}
				//bottom
				if(redsPBbottom==null && redsGB.bottom!=null)
				{
					var conductVObottom:ConductVO = new ConductVO();
					conductVObottom.target = redsPB;
					conductVObottom.newDest = redsGB.bottom.centerPointXY;
					conductVObottom.newPosition = redsGB.bottom.position;
					tempAC.addItem(conductVObottom);
				}else
				{
					if(redsPBbottomBottom==null && redsGB.bottom!=null && redsGB.bottom.bottom!=null)
					{
						var conductVObottomBottom:ConductVO = new ConductVO();
						conductVObottomBottom.target = redsPB;
						conductVObottomBottom.newDest = redsGB.bottom.bottom.centerPointXY;
						conductVObottomBottom.newPosition = redsGB.bottom.bottom.position;
						tempAC.addItem(conductVObottomBottom);
					}
				}
				//lowerLeft
				if(redsPBlowerLeft==null && redsGB.lowerLeft!=null)
				{
					var conductVOlowerLeft:ConductVO = new ConductVO();
					conductVOlowerLeft.target = redsPB;
					conductVOlowerLeft.newDest = redsGB.lowerLeft.centerPointXY;
					conductVOlowerLeft.newPosition = redsGB.lowerLeft.position;
					tempAC.addItem(conductVOlowerLeft);
				}else
				{
					if(redsPBlowerLeftLowerLeft==null && redsGB.lowerLeft!=null && redsGB.lowerLeft.lowerLeft!=null)
					{
						var conductVOlowerLeftLowerLeft:ConductVO = new ConductVO();
						conductVOlowerLeftLowerLeft.target = redsPB;
						conductVOlowerLeftLowerLeft.newDest = redsGB.lowerLeft.lowerLeft.centerPointXY;
						conductVOlowerLeftLowerLeft.newPosition = redsGB.lowerLeft.lowerLeft.position;
						tempAC.addItem(conductVOlowerLeftLowerLeft);
					}
				}
				//lowerRight
				if(redsPBlowerRight==null && redsGB.lowerRight!=null)
				{
					var conductVOlowerRight:ConductVO = new ConductVO();
					conductVOlowerRight.target = redsPB;
					conductVOlowerRight.newDest = redsGB.lowerRight.centerPointXY;
					conductVOlowerRight.newPosition = redsGB.lowerRight.position;
					tempAC.addItem(conductVOlowerRight);
				}else
				{
					if(redsPBlowerRightLowerRight==null && redsGB.lowerRight!=null && redsGB.lowerRight.lowerRight!=null)
					{
						var conductVOlowerRightLowerRight:ConductVO = new ConductVO();
						conductVOlowerRightLowerRight.target = redsPB;
						conductVOlowerRightLowerRight.newDest = redsGB.lowerRight.lowerRight.centerPointXY;
						conductVOlowerRightLowerRight.newPosition = redsGB.lowerRight.lowerRight.position;
						tempAC.addItem(conductVOlowerRightLowerRight);
					}
				}
				//upperRight
				if(redsPBupperRight==null && redsGB.upperRight!=null)
				{
					var conductVOupperRight:ConductVO = new ConductVO();
					conductVOupperRight.target = redsPB;
					conductVOupperRight.newDest = redsGB.upperRight.centerPointXY;
					conductVOupperRight.newPosition = redsGB.upperRight.position;
					tempAC.addItem(conductVOupperRight);
				}else
				{
					if(redsPBupperRightUpperRight==null && redsGB.upperRight!=null && redsGB.upperRight.upperRight!=null)
					{
						var conductVOupperRightUpperRight:ConductVO = new ConductVO();
						conductVOupperRightUpperRight.target = redsPB;
						conductVOupperRightUpperRight.newDest = redsGB.upperRight.upperRight.centerPointXY;
						conductVOupperRightUpperRight.newPosition = redsGB.upperRight.upperRight.position;
						tempAC.addItem(conductVOupperRightUpperRight);
					}
				}
				//upperLeft
				if(redsPBupperLeft==null && redsGB.upperLeft!=null)
				{
					var conductVOupperLeft:ConductVO = new ConductVO();
					conductVOupperLeft.target = redsPB;
					conductVOupperLeft.newDest = redsGB.upperLeft.centerPointXY;
					conductVOupperLeft.newPosition = redsGB.upperLeft.position;
					tempAC.addItem(conductVOupperLeft);
				}else
				{
					if(redsPBupperLeftUpperLeft==null && redsGB.upperLeft!=null && redsGB.upperLeft.upperLeft!=null)
					{
						var conductVOupperLeftUpperLeft:ConductVO = new ConductVO();
						conductVOupperLeftUpperLeft.target = redsPB;
						conductVOupperLeftUpperLeft.newDest = redsGB.upperLeft.upperLeft.centerPointXY;
						conductVOupperLeftUpperLeft.newPosition = redsGB.upperLeft.upperLeft.position;
						tempAC.addItem(conductVOupperLeftUpperLeft);
					}	
				}
			}
			trace("all possibility moves @GameAIBase:");
			for(var z:int=0;z<tempAC.length;z++)
			{
				trace("moves[",z,"]:",
					(tempAC.getItemAt(z) as ConductVO).target,
					"[",
					(tempAC.getItemAt(z) as ConductVO).target.pieceVO.position,
					"]",
					"to",
					(tempAC.getItemAt(z) as ConductVO).newPosition);
			}
			
			trace("#####################Game AI generateMoves end##########################");
			return tempAC;
		}
		
		public function applyMovement(conductVO:ConductVO):Array2
		{
			PiecesModel.getInstance().selectedPiece = conductVO.target;
			trace("PiecesModel.getInstance().selectedPiece@GameAIBase.applyMove:",PiecesModel.getInstance().selectedPiece);
			PiecesManager.tryMovement( conductVO.target,conductVO.newDest,conductVO.newPosition );
			return BoardModel.getInstance().gamePosition;
		}
		
		public function doEvaluation(conductVO:ConductVO):int
		{
			//TODO: implement function
			
			return positionEvaluation;
		}
	}
}